package org.jetlinks.community.mstn.web;


import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.authorization.annotation.*;
import org.jetlinks.community.auth.enums.OrgType;
import org.jetlinks.community.auth.enums.RoleState;
import org.jetlinks.community.auth.enums.RoleType;
import org.jetlinks.community.auth.service.OrganizationService;
import org.jetlinks.community.mstn.entity.vo.TenantCreateReqVO;
import org.jetlinks.community.mstn.entity.vo.TenantListResVO;
import org.jetlinks.community.mstn.service.TenantService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import java.util.List;

@RestController
@RequestMapping("/mstn/tenant")
@Authorize
@Resource(id = "tenant", name = "租户管理", group = "mstn")
@Tag(name = "租户管理")
@AllArgsConstructor
public class TenantController {

    private final TenantService tenantService;

    private final OrganizationService organizationService;


    @PostMapping("/list")
    public Mono<PagerResult<TenantListResVO>> list(@RequestBody Mono<QueryParamEntity> param) {
        return param.doOnNext( queryParamEntity -> {
            List<Term> terms = queryParamEntity.getTerms();
            //查询出角色为租户
            Term roleTypeTerm = new Term();
            roleTypeTerm.setColumn("j_1.roleType");
            roleTypeTerm.setValue(RoleType.tenant);
            terms.add(roleTypeTerm);
            //查询出机构为项目的
            Term orgTypeTerm = new Term();
            orgTypeTerm.setColumn("orgType");
            orgTypeTerm.setValue(OrgType.project);
            terms.add(orgTypeTerm);

            //查询出用户为租户的
            Term userTypeTerm = new Term();
            userTypeTerm.setColumn("j_2.type");
            userTypeTerm.setValue(RoleType.tenant);
            terms.add(userTypeTerm);
        }).flatMap(tenantService::projectList);
    }

    @PostMapping
    @CreateAction
    @Operation(summary = "创建租户")
    @Transactional
    public Mono<String> create(@RequestBody TenantCreateReqVO createReqVO) {
        return tenantService.saveTenant(createReqVO);
    }

    @PutMapping
    @SaveAction
    @Operation(summary = "修改租户")
    @Transactional
    public Mono<String> update(@RequestBody TenantCreateReqVO createReqVO) {
        return tenantService.saveTenant(createReqVO);
    }


    @PutMapping("/{id}/enabled")
    @SaveAction
    @Operation(summary = "启用租户")
    public Mono<Integer> enabled(@PathVariable String id) {
        return tenantService.updateTenantState(id ,RoleState.enabled);
    }

    @PutMapping("/{id}/disabled")
    @SaveAction
    @Operation(summary = "禁用租户")
    public Mono<Integer> disabled(@PathVariable String id) {
        return tenantService.updateTenantState(id ,RoleState.disabled);
    }


    @PostMapping("/{id}/users/_bind")
    @ResourceAction(id = "bind-user", name = "绑定用户")
    @Operation(summary = "绑定用户到租户")
    public Mono<Integer> bindUser(@Parameter(description = "机构ID") @PathVariable String id,
                                  @Parameter(description = "用户ID")
                                  @RequestBody Mono<List<String>> userId) {

        return userId.flatMap(list -> organizationService.bindTenantUser(id, list));

    }

    @PostMapping("/{id}/users/_unbind")
    @ResourceAction(id = "unbind-user", name = "解绑用户")
    @Operation(summary = "从租户解绑用户")
    public Mono<Integer> unbindUser(@Parameter(description = "机构ID") @PathVariable String id,
                                    @Parameter(description = "用户ID")
                                    @RequestBody Mono<List<String>> userId) {
        return userId.flatMap(list -> organizationService.unbindTenantUser(id, list));
    }

    @PostMapping("/{type}/{userId}/users/_bind")
    @ResourceAction(id = "bind-user-org", name = "绑定用户到站点/分组")
    @Operation(summary = "绑定用户到站点/分组")
    public Mono<Integer> bindUserOrg(
        @Parameter(description = "机构类型") @PathVariable String type,
        @Parameter(description = "机构ID") @PathVariable String userId,
                                  @Parameter(description = "用户ID")
                                  @RequestBody Mono<List<String>> orgIds) {
        return orgIds.flatMap(list -> tenantService.bindUserToOrg(userId, list, type));
    }

    @PostMapping("/{type}/{userId}/users/_unbind")
    @ResourceAction(id = "unbind-user-org", name = "解除绑定用户到站点/分组")
    @Operation(summary = "解除绑定用户到站点/分组")
    public Mono<Integer> unbindUserOrg(
        @Parameter(description = "机构类型") @PathVariable String type,
        @Parameter(description = "机构ID") @PathVariable String userId,
        @Parameter(description = "用户ID")
        @RequestBody Mono<List<String>> orgIds) {
        return orgIds.flatMap(list -> tenantService.unbindUserToOrg(userId, list, type));
    }
}
